import requests
import subprocess
import time
import re
import sys
import os

class WiFiManager:
    def __init__(self):
        # Check if the operating system is POSIX-compliant
        if os.name != "posix":
            print("This program is intended to be run on UNIHIKER.")
            print("未连接行空板")
            sys.exit(1)  # Exit the program with a non-zero exit code to indicate an error
        self.nmcli_base_cmd = "nmcli -t -f"
        self.wlan_interface = "wlan0"
 
    def run_command(self, command):
        result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, shell=True)
        if result.returncode == 0:
            return result.stdout.strip()
        else:
            raise Exception(f"Error executing command '{command}': {result.stderr}")

    def get_wifi_ssid(self):
        if self.is_wifi_connected():
            try:
                connection_name = self.run_command(f"{self.nmcli_base_cmd} NAME connection show --active | grep wifi")
                if connection_name:
                    ssid = self.run_command(f"{self.nmcli_base_cmd} 802-11-wireless.ssid connection show '{connection_name}'")
                    ssid = ssid.split(':', 1)[-1].strip()
                    return ssid
                else:
                    return None
            except Exception as e:
                print(f"Error getting active wifi connection: {e}")
                return None
        return None

    def connect_wifi(self, ssid, password):
        active_ssid = self.get_wifi_ssid()
        if active_ssid is not None:
            print(f"Currently connected to WiFi SSID: {active_ssid}")
        else:
            print("No WiFi connection detected.")
        if active_ssid == ssid:
            print(f"Already connected to the correct WiFi: {ssid}")
            return True
        try:
            for i in range(1, 4):
                print("scanning...")
                requests.get("http://10.1.2.3/wifi/scan")
                time.sleep(2)
                print("connecting wifi...")
                url = f"http://10.1.2.3/wifi/connect?ssid={ssid}&password={password}"
                response = requests.get(url)
                response.raise_for_status()
                response = response.json()
                time_value = time.time()
                print(f"Waiting for connection to WiFi: {ssid}")
                while True:
                    time.sleep(0.1)
                    print(".", end="")
                    sys.stdout.flush()
                    new_active_ssid = self.get_wifi_ssid()
                    if new_active_ssid == ssid:
                        print('')
                        print(f"Successfully connected to WiFi: {ssid}")
                        return True
                    if time.time() - time_value > 30:
                        print('')
                        print(f"Connection timeout.Retry:({i}/3)")
                        break
            print("Wi-Fi connection failed, please check the name or password.")
            return False
        except requests.exceptions.HTTPError as http_err:
            print(f"HTTP error occurred: {http_err}")
        except Exception as err:
            print(f"An error occurred: {err}")
            return False

    def get_wifi_device(self):
        try:
            get_wifi_device_name = self.run_command(f"{self.nmcli_base_cmd} DEVICE,STATE dev status")
            get_wifi_device_name = self.run_command(f"{self.nmcli_base_cmd} DEVICE,STATE dev status | grep '^wlan0:connected' | cut -d: -f1")
            return get_wifi_device_name
        except Exception as e:
            print(f"Error getting active wifi connection: {e}")
        return None

    def get_wifi_status(self):
        get_wifi_status = self.run_command(f"{self.nmcli_base_cmd} DEVICE,STATE dev status | grep wlan0 | cut -d':' -f 2")
        return get_wifi_status

    def is_wifi_connected(self):
        status = self.get_wifi_status()
        return status == "connected"

    def get_wifi_ip_address(self):
        device_ip = self.run_command(f"{self.nmcli_base_cmd} IP4.ADDRESS dev show {self.wlan_interface}")
        match = re.search(r'\b(?:\d{1,3}\.){3}\d{1,3}\b', device_ip)
        return match.group() if match else "0.0.0.0"

    def get_wifi_mac_address(self):
        mac = self.run_command(f"{self.nmcli_base_cmd} GENERAL.HWADDR dev show {self.wlan_interface}")
        match = re.search(r'((?:[\da-fA-F]{2}:){5}[\da-fA-F]{2})', mac)
        return match.group() if match else "00:00:00:00:00:00"

    def get_wifi_gateway(self):
        gateway = self.run_command(f"{self.nmcli_base_cmd} IP4.GATEWAY dev show {self.wlan_interface}")
        match = re.search(r'\b(?:\d{1,3}\.){3}\d{1,3}\b', gateway)
        return match.group() if match else "0.0.0.0"

    def break_wifi_connect(self):
        result = subprocess.run(["nmcli", "dev", "disconnect", self.wlan_interface], capture_output=True, text=True)
        if result.returncode == 0:
            print("Disconnected successfully.")
            return True
        else:
            print("Failed to disconnect: Wi-Fi still connected.")
            return False